package ei

import (
	"errors"
	"fmt"
	"math"
	"runtime/debug"
	"strconv"
)

type Token struct {
	TypeClass typeClass
	Value     interface{}
}

func (self Token) Str() string {
	var v, typeName string
	switch self.TypeClass {
	case TYPE_SPC:
		return ""
	case TYPE_FLOAT:
		v = strconv.FormatFloat(self.Value.(float64), 'f', 4, 64)
		typeName = "Float"
	case TYPE_STRING:
		v = self.Value.(string)
		typeName = "String"
	case TYPE_SYMBOL:
		v = self.Value.(string)
		typeName = "Symbol"
	case TYPE_TXT: // Txt指代的仅仅是文本，而不是字符串（不一定是字符串变量）
		v = self.Value.(string)
		typeName = "Txt"
	case TYPE_LIST:
		v = "len: " + strconv.Itoa(len(self.Value.([]Token))) + ": "
		for i := 0; i < len(self.Value.([]Token)); i++ {
			v += self.Value.([]Token)[i].Str()
		}
		typeName = "List"
	case TYPE_ARGS:
		v = "len: " + strconv.Itoa(len(self.Value.([]Token)))
		typeName = "Args"
	case TYPE_EXPR:
		exp := self.Value.(Expr)
		v = exp.Str("")
		typeName = "Expr"
	case TYPE_TAGET:
		if self.Value == "?" {
			v = "?"
		} else {
			v = "?" + self.Value.(string)
		}
		typeName = "Target"
	case TYPE_INDEX:
		v = strconv.Itoa(self.ToInt())
		typeName = "Index"
	case TYPE_STRUCT:
		for key, value := range self.Value.(map[string]Token){
			v += key + ":" + value.ValueStr() + "; "
		}
		typeName = "Struct"
	case TYPE_FIELD:
		v = self.Value.(string)
		typeName = "Field"
	case TYPE_PTR:
		v = self.Value.(VarPtr).name + ":" + GetPtrValue(self).Str()
		typeName = "Ptr"
	default:
		v = "！无法识别！ type:" + strconv.Itoa(int(self.TypeClass))
	}
	return "{" + typeName + "," + v + "}"
}

func (self Token) ValueStr() string {
	switch self.TypeClass {
	case TYPE_SPC:
		return ""
	case TYPE_FLOAT:
		return strconv.FormatFloat(self.Value.(float64), 'f', 4, 64)
	case TYPE_STRING:
		return self.Value.(string)
	case TYPE_SYMBOL:
		return self.Value.(string)
	case TYPE_TXT: // Txt指代的仅仅是文本，而不是字符串（不一定是字符串变量）
		return self.Value.(string)
	case TYPE_LIST:
		parseToken := self.Value.([]Token)
		var r string = "("
		for i := 0; i < len(parseToken); i++ {
			r += parseToken[i].ValueStr() + ", "
		}
		r += ")"
		return r
	default:
		return "！无法识别！"
	}
}

func (self Token) ToFloat64() float64 {
	return GetFloat64(self)
}

func (self Token) ToFloat32() float32 {
	return GetFloat32(self)
}

func (self Token) ToInt() int {
	return Getint(self)
}

func (self Token) Print() {
	print(self.Str())
}

type calMode int

const (
	MODE_CAL   calMode = 0 // 正常计算模式
	MODE_SOLVE calMode = 1 // 解方程模式
)

type Process int

const (
	PROCESS_READY    Process = 0
	PROCESS_READCHAR Process = 1
	PROCESS_EXPLAIN  Process = 2
	PROCESS_CAL      Process = 3
	PROCESS_FINISH   Process = 4
)

type Interpreter struct {
	str             []rune
	readState       readState
	charTmp         string
	tokens          []Token
	Mem             VarMemManager
	FunMem          FunMemManager
	RawFunMem       RawFunMemManager
	mode            calMode
	AdvPrec         float64 // 导数等的精度
	InVar           float64 // 解方程的当前值
	targetChangeAdd float64 // 自变量变化delta
	targetChangeMul	float64 // 自变量变化乘以该值，设置为0以消除变量影响
	Process         Process
	Expr            []Expr
	UsePanic        bool // 是否panic错误，（通过run()捕捉错误并输出）
}

func CreateInterpreter() Interpreter {
	ip := Interpreter{
		str:             []rune{},
		readState:       is_any,
		charTmp:         "",
		tokens:          []Token{},
		Mem:             CreateMemManager(),
		FunMem:          CreateFunMemManager(),
		RawFunMem:       CreateRawFunMemManager(),
		mode:            MODE_CAL,
		AdvPrec:         0.0000001,
		InVar:           0, // independent variable 自变量
		targetChangeAdd: 0,
		targetChangeMul: 1,
		Process:         PROCESS_READY,
		Expr:            nil,
		UsePanic:        false,
	}
	addAdvMathEx(&ip)
	addFinBoxEx(&ip)
	return ip
}

func (ip *Interpreter) Print() {
	println("当前状态：")
	println("Process", ip.Process)
	print("Tokens:")
	for i := 0; i < len(ip.tokens); i++ {
		ip.tokens[i].Print()
	}
	println("")
}

func CreateFromString(expr string) Interpreter {
	ip := CreateInterpreter()
	ip.str = []rune(expr)
	ip.ReadChars()
	ip.CreateAST()
	return ip
}

func (self *Interpreter) RunSimple(expr string) {
	t, err := self.Run(expr)
	if err == nil {
		println(t.ValueStr())
	} else {
		println("执行出错")
		fmt.Println(err)
		self.Print()
		if self.UsePanic {
			panic(err)
		} else {
			debug.PrintStack()
		}
	}
}

func (self *Interpreter) Run(expr string) (t Token, err error) {
	//defer func() {
	//	if errRev := recover(); errRev != nil {
	//		err = errors.New(errRev.(string))
	//	}
	//}()
	self.Reset()
	self.tokens = []Token{}
	self.str = []rune(expr)
	// self.ReadChars()
	self.tokens = char2Token(self.str, defFixSymbol)
	self.CreateAST()
	r := self.Cal()
	if len(r) > 2 {
		return Token{
			TypeClass: TYPE_LIST,
			Value:     r,
		}, nil
	} else if len(r) == 0 {
		return SpcToken(), errors.New("没有执行任何内容")
	} else {
		return r[0], nil
	}
}

func (self *Interpreter) Reset() {
	self.targetChangeMul = 1
	self.targetChangeAdd = 0
	self.mode = 0
}

func (self *Interpreter) ReadChars() {
	// 初始化解释器状态
	self.Process = PROCESS_READCHAR
	self.mode = MODE_CAL
	for i := 0; i < len(self.str); i++ {
		char := self.str[i]
		switch getCharType(char) {
		case CHAR_TYPE_SPACE:

		case CHAR_TYPE_NUMBER_DIGIT:
			if self.readState != is_txt { // 支持英文+数字的变量形式
				self.stateChange(is_number)
			}
			self.charTmp += string(char)
		case CHAR_TYPE_SYMBOL:
			if char == 0x002E && self.readState == is_number { // 支持小数
				self.charTmp += string(char)
			} else if char == 0x0028 { // 括号
				self.stateChange(is_para_S)
				self.tokens = append(self.tokens, Token{TypeClass: TYPE_SYMBOL, Value: string(char)})
			} else if char == 0x0029 {
				self.stateChange(is_para_E)
				self.tokens = append(self.tokens, Token{TypeClass: TYPE_SYMBOL, Value: string(char)})
			} else if char == 0x002C {
				self.stateChange(is_any)
				self.tokens = append(self.tokens, Token{TypeClass: TYPE_SYMBOL, Value: string(char)})
			} else if char == 0x005F {
				self.stateChange(is_txt)
				self.charTmp += string(char)
			} else if char == 0x003F {
				self.mode = MODE_SOLVE
				self.stateChange(is_any)
				self.tokens = append(self.tokens, Token{TypeClass: TYPE_TAGET, Value: string(char)})
			} else {
				self.stateChange(is_symbol)
				self.charTmp += string(char)
			}
		case CHAR_TYPE_LETTER_A, CHAR_TYPE_LETTER_a:
			if self.readState == is_txt {
				self.charTmp += string(char)
			} else {
				self.stateChange(is_txt)
				self.charTmp += string(char)
			}
		case CHAR_TYPE_CTRL:
			continue
		default:
			panic("无法识别字符" + string(char) + strconv.Itoa(int(char)))
		}
	}
	self.stateChange(is_any)
	self.str = make([]rune, 0)
}

func (self *Interpreter) stateChange(new readState) {
	if self.readState == new { // 类型其实并没有改变
		return
	} else {
		if len(self.charTmp) > 0 {
			switch self.readState {
			case is_any:
				panic("异常字符解析状态") // any是未读取时的状态，读取第一个字符就会改变，len此时为0
			case is_number: // 所有数字都记录为float64
				v, err := strconv.ParseFloat(self.charTmp, 64)
				if checkErr(err) {
					self.tokens = append(self.tokens, Token{TypeClass: TYPE_FLOAT, Value: v})
				}
				if new == is_txt || new == is_para_S {
					self.tokens = append(self.tokens, Token{TypeClass: TYPE_SYMBOL, Value: "*"})
				}
			case is_symbol:
				self.tokens = append(self.tokens, Token{TypeClass: TYPE_SYMBOL, Value: self.charTmp})
			case is_txt:
				self.tokens = append(self.tokens, Token{TypeClass: TYPE_TXT, Value: self.charTmp})
			}
		}
		self.readState = new
		self.charTmp = ""
	}
}

func (self *Interpreter) Cal() []Token {
	self.Process = PROCESS_CAL
	result := make([]Token, len(self.Expr))
	for i := 0; i < len(self.Expr); i++ {
		r := self.Expr[i].Cal(self, false)
		for r.TypeClass == TYPE_EXPR{
			recal := r.Value.(Expr)
			r = recal.Cal(self, false)
		}
		self.Expr = self.Expr[1:]
		result[i] = r
	}
	self.Process = PROCESS_FINISH
	return result
}

func (self *Interpreter) AddFunc(fName string, f func(t Token) Token) {
	self.FunMem.SetValue(fName, f)
}

func (self *Interpreter) AddRawFun(fName string, f func(ip *Interpreter, v []Expr) Token) {
	self.RawFunMem.SetValue(fName, f)
}

type Expr struct {
	op   string
	args []Expr
	v    Token
}

func (self *Expr) Str(tab string) string {
	ret := tab
	if self.args == nil {
		ret += tab + self.v.Str() + "\n"
	} else {
		ret += tab + "Op " + self.op + "\n"
		for i := 0; i < len(self.args); i++ {
			ret += self.args[i].Str(tab + "    ")
		}
	}
	return ret
}

func (self *Expr) Print(tab string) {
	if self.args == nil {
		print(tab)
		self.v.Print()
		print("\n")
	} else {
		print(tab, "Op", self.op, "\n")
		for i := 0; i < len(self.args); i++ {
			self.args[i].Print(tab + "    ")
		}
	}
}

func (self *Expr) FindElementsByType(typeToFind typeClass) []Token {
	var t []Token
	if self.args == nil {
		if self.v.TypeClass == typeToFind {
			return []Token{self.v}
		} else {
			return []Token{}
		}
	} else {
		for i := 0; i < len(self.args); i++ {
			t = append(t, self.args[i].FindElementsByType(typeToFind)...)
		}
		return t
	}
}

func (self *Expr) FindInVarNames() []string {
	var result []string
	tokens := self.FindElementsByType(TYPE_TAGET)
	LOOP:for _, t := range tokens{
		for _, r := range result{
			if r == t.Value.(string) {
				continue LOOP
			}
		}
		result = append(result, t.Value.(string))
	}
	return result
}

func (self *Expr) Cal(ip *Interpreter, substituting bool) Token { // substituting是否带入未知数
	if self.args == nil {
		switch self.v.TypeClass {
		case TYPE_TXT:
			return ip.Mem.MustGetPtr(self.v.Value.(string))
		case TYPE_TAGET:
			if substituting {
				return FromFloat64(ip.Mem.MustGetPtr(self.v.Value.(string)).ToFloat64() * ip.targetChangeMul + ip.targetChangeAdd)
			} else {
				return Token{
					TypeClass: TYPE_EXPR,
					Value:     self.v,
				}
			}
		}
		return self.v
	} else {
		if self.op == "=" {
			if len(self.args) != 2 {
				panic("操作=的参数不足")
			}
			right := self.args[1].Cal(ip, substituting)
			println("右侧值为", right.Str())
			if len(self.FindElementsByType(TYPE_TAGET)) > 0 { // 操作为解方程
				zeroFn := Expr{
					op:   "-",
					args: []Expr{self.args[0], self.args[1]},
					v:    Token{},
				}
				return solve(zeroFn, *ip, ip.InVar)
			} else { // 操作为变量赋值

			}
		}
		var arg = make([]Token, len(self.args))
		var argPtr = make([]Token, len(self.args))
		for i := 0; i < len(self.args); i++ {
			argPtr[i] = self.args[i].Cal(ip, substituting)
			arg[i] = MustGetPtrValue(argPtr[i])
			if arg[i].TypeClass == TYPE_EXPR { // 存在 自变量
				v, ok := ip.runMemRawFun(self.op, self.args)
				if ok {
					return v
				} else {
					// 判断这个Op有没有定义
					ok = ifBuiltInOp(self.op)
					if ok {
						return Token{
							TypeClass: TYPE_EXPR,
							Value:     *self,
						}
					} else {
						_, ok := ip.FunMem.GetValue(self.op)
						if ok {
							return Token{
								TypeClass: TYPE_EXPR,
								Value:     *self,
							}
						} else {
							panic("未定义函数：" + self.op)
						}
					}
				}
			}
		}
		// 至此arg一定不含?
		switch self.op {
		case "=":
			if argPtr[0].TypeClass != TYPE_PTR {
				panic("=左侧不是变量")
			}
			println("变量", argPtr[0].Str(), "定义为", arg[1].Str())
			SetPtrValue(argPtr[0], arg[1])
			return SpcToken()
		case "+":
			if len(arg) != 2 {
				panic("操作+的参数不足")
			}
			return FromFloat64(GetFloat64(arg[0]) + GetFloat64(arg[1]))
		case "-":
			if len(arg) != 2 {
				panic("操作-的参数不足")
			}
			return FromFloat64(GetFloat64(arg[0]) - GetFloat64(arg[1]))
		case "*":
			if len(arg) != 2 {
				panic("操作*的参数不足")
			}
			return FromFloat64(GetFloat64(arg[0]) * GetFloat64(arg[1]))
		case "/":
			if len(arg) != 2 {
				panic("操作/的参数不足")
			}
			return FromFloat64(GetFloat64(arg[0]) / GetFloat64(arg[1]))
		case "^":
			if len(arg) != 2 {
				panic("操作^的参数不足")
			}
			return FromFloat64(math.Pow(arg[0].ToFloat64(), arg[1].ToFloat64()))
		case "_array_get":
			if len(arg) != 2 {
				panic("操作 获取数组变量 的参数不足")
			}
			if arg[0].TypeClass != TYPE_LIST{
				panic("取得下标的变量不是数组")
			}

			return arg[0].Value.([]Token)[arg[1].ToInt()]
		case ".":
			if len(arg) != 2 {
				panic("操作 读取字段 的参数不足")
			}
			if arg[0].TypeClass != TYPE_STRUCT{
				panic("操作的对象不是结构体")
			}
			if arg[1].TypeClass != TYPE_FIELD {
				panic("操作数不是字段名")
			}
			return arg[0].Value.(map[string]Token)[arg[1].Value.(string)]
		case "printToken":
			var str string
			for _, a := range arg{
				a.Print()
				str += a.Str()
			}
			return Token{
				TypeClass: TYPE_STRING,
				Value:     str,
			}
		default:
			v, ok := ip.runMemFun(self.op, arg)
			if !ok {
				v, ok = ip.runMemRawFun(self.op, self.args)
				if !ok {
					panic("无法识别符号" + self.op)
				} else {
					return v
				}
			} else {
				return v
			}
		}
	}
}

func (self *Interpreter) runMemFun(fName string, args []Token) (Token, bool) {
	v, ok := self.FunMem.GetValue(fName)
	if !ok {
		return SpcToken(), false
	} else {
		return v(AsGroup(args)), true
	}
}

func (self *Interpreter) runMemRawFun(fName string, argExpr []Expr) (Token, bool) {
	fn, ok := self.RawFunMem.GetValue(fName)
	if !ok {
		return SpcToken(), false
	} else {
		return fn(self, argExpr), true
	}
}

func ifBuiltInOp(op string) bool {
	BuiltIn := []string{"+", "-", "*", "/", "^", "="}
	for _, v := range BuiltIn {
		if op == v {
			return true
		}
	}
	return false
}

func ExplainParenthesis(t []Token) []Token {
	// 解析 ()
	handleTokenGroup(&t, func(t *[]Token) {
		var layout [][]Token
		var layoutPos = 0
		layout = append(layout, []Token{})
		for i := 0; i < len(*t); i++ {
			if (*t)[i].TypeClass == TYPE_SYMBOL && (*t)[i].Value == "(" {
				layout = append(layout, []Token{})
				layoutPos++
			} else if (*t)[i].TypeClass == TYPE_SYMBOL && (*t)[i].Value == ")" {
				var tc typeClass // 区分括号表示参数还是数组
				if layoutPos > 0 && len(layout[layoutPos-1]) > 0 {
					if layout[layoutPos-1][len(layout[layoutPos-1])-1].TypeClass == TYPE_TXT {
						tc = TYPE_ARGS
						layout[layoutPos-1][len(layout[layoutPos-1])-1].TypeClass = TYPE_FUNC
					} else {
						tc = TYPE_LIST
					}
				} else {
					tc = TYPE_LIST
				}
				layout[layoutPos-1] = append(layout[layoutPos-1], Token{TypeClass: tc, Value: layout[layoutPos]})
				layout = layout[:layoutPos] // 删除
				layoutPos--
			} else {
				layout[layoutPos] = append(layout[layoutPos], (*t)[i])
			}
		}
		if layoutPos != 0 {
			panic("括号数量不匹配")
		}
		*t = make([]Token, len(layout[0]))
		*t = layout[0]
	})

	// 解析 []
	handleTokenGroup(&t, func(t *[]Token) {
		var layout [][]Token
		var layoutPos = 0
		layout = append(layout, []Token{})
		for i := 0; i < len(*t); i++ {
			if (*t)[i].TypeClass == TYPE_SYMBOL && (*t)[i].Value == "[" {
				// TODO 从解释器中检查变量
				layout = append(layout, []Token{})
				layoutPos++
			} else if (*t)[i].TypeClass == TYPE_SYMBOL && (*t)[i].Value == "]" {
				layout[layoutPos-1] = append(layout[layoutPos-1], Token{TypeClass: TYPE_INDEX, Value: layout[layoutPos]})
				layout = layout[:layoutPos] // 删除
				layoutPos--
			} else {
				layout[layoutPos] = append(layout[layoutPos], (*t)[i])
			}
		}
		if layoutPos != 0 {
			panic("括号数量不匹配")
		}
		*t = make([]Token, len(layout[0]))
		*t = layout[0]
	})
	return t
}

func ExplainSymbol(t []Token) []Token {
	var token = t
	for i := 0; i < len(token); i++ {
		if token[i].TypeClass == TYPE_ARGS || token[i].TypeClass == TYPE_LIST { // TODO 区分直接输入的数组和数组变量
			r := ExplainSymbol(token[i].Value.([]Token))
			if len(r) > 1 || token[i].TypeClass == TYPE_ARGS {
				r = createList(r)
				token[i] = Token{
					TypeClass: token[i].TypeClass, // 保持类型不变，解析括号时已经标记类型
					Value:     r,
				}
				if token[i].TypeClass == TYPE_ARGS {
					tmp := token[i+1:]
					expr := createExpr(token[i-1], token[i])
					token = append(token[:i-1], expr)
					token = append(token, tmp...)
					continue
				}
			} else {
				if len(r) == 1 {
					token[i] = r[0]
				} else {
					println("警告：存在空白括号")
				}
			}
		}
		if token[i].TypeClass == TYPE_INDEX {
			tmp := token[i+1:]
			explainedToken := ExplainSymbol(token[i].Value.([]Token))
			if len(explainedToken) != 1 {
				panic("无法解析要求的数组下标，给定关键词数量错误")
			}
			expr := createExpr(Token{Value:"_array_get"}, token[i-1], explainedToken[0])
			token = append(token[:i-1], expr)
			token = append(token, tmp...)
			i--
		}
	}
	for i := 0; i < len(token); i++ {
		if token[i].TypeClass == TYPE_TAGET {
			if len(token) > i+1 && token[i+1].TypeClass==TYPE_TXT {
				token[i].Value = token[i+1].Value.(string)
				token = append(token[:i+1], token[i+2:]...)
			}
		}
	}
	for i := 0; i < len(token); i++ {
		if token[i].TypeClass == TYPE_SYMBOL && (token[i].Value == ".") {
			tmp := token[i+2:]
			token[i+1].TypeClass = TYPE_FIELD
			expr := createExpr(token[i], token[i-1], token[i+1])
			token = append(token[:i-1], expr)
			token = append(token, tmp...)
			i--
		}
	}
	for i := 0; i < len(token); i++ {
		if token[i].TypeClass == TYPE_SYMBOL && (token[i].Value == "^") {
			tmp := token[i+2:]
			expr := createExpr(token[i], token[i-1], token[i+1])
			token = append(token[:i-1], expr)
			token = append(token, tmp...)
			i--
		}
	}
	for i := 0; i < len(token); i++ {
		if token[i].TypeClass == TYPE_SYMBOL && (token[i].Value == "*" || token[i].Value == "/") {
			tmp := token[i+2:]
			expr := createExpr(token[i], token[i-1], token[i+1])
			token = append(token[:i-1], expr)
			token = append(token, tmp...)
			i--
		}
	}
	for i := 0; i < len(token); i++ {
		if token[i].TypeClass == TYPE_SYMBOL && (token[i].Value == "+" || token[i].Value == "-") {
			if i == 0 {
				tmp := token[i+2:]
				expr := createExpr(token[i], FromFloat64(0), token[i+1])
				token = append(token[:0], expr)
				token = append(token, tmp...)
				i--
			} else {
				tmp := token[i+2:]
				expr := createExpr(token[i], token[i-1], token[i+1])
				token = append(token[:i-1], expr)
				token = append(token, tmp...)
				i--
			}
		}
	}
	for i := 0; i < len(token); i++ {
		if token[i].TypeClass == TYPE_SYMBOL && (token[i].Value == "=") {
			tmp := token[i+2:]
			expr := createExpr(token[i], token[i-1], token[i+1])
			token = append(token[:i-1], expr)
			token = append(token, tmp...)
			i--
		}
	}
	return token
}

func (self *Interpreter) CreateAST() {
	self.Process = PROCESS_EXPLAIN
	self.Expr = append(self.Expr, CreateAST(self.tokens))
}

func CreateAST(t []Token) Expr {
	ped := ExplainParenthesis(t)
	es := ExplainSymbol(ped)
	if len(es) > 1 {
		var s string
		for i, e := range es {
			s += strconv.Itoa(i) + " :" + e.Str() + "\n"
		}
		panic("存在分离元素，无法解析语法！AST解析结果如下：\n" + s)
	}
	token := es[0]
	if token.TypeClass == TYPE_EXPR {
		e := token.Value.(Expr)
		e.Print("")
		return token.Value.(Expr)
	} else {
		println("Warning: 没有解析到内容")
		return Expr{
			op:   "",
			args: nil,
			v:    token,
		}
	}
}

func createExpr(op Token, token ...Token) Token {
	vExpr := make([]Expr, 0, len(token))
	for i := 0; i < len(token); i++ {
		if token[i].TypeClass == TYPE_ARGS {
			return createExpr(op, token[i].Value.([]Token)...)
		}
		if token[i].TypeClass != TYPE_EXPR {
			singleExpr := Expr{
				op:   "Expr",
				args: nil,
				v:    token[i],
			}
			vExpr = append(vExpr, singleExpr)
		} else {
			vExpr = append(vExpr, token[i].Value.(Expr))
		}
	}
	return Token{
		TypeClass: TYPE_EXPR,
		Value: Expr{
			op:   op.Value.(string),
			args: vExpr,
			v:    Token{},
		},
	}
}

func createList(t []Token) []Token {
	var r []Token
	for i := 0; i < len(t); i++ {
		if t[i].TypeClass == TYPE_SYMBOL {
			if t[i].Value.(string) == "," {
				continue
			}
		}
		r = append(r, t[i])
	}
	return r
}

type memNode struct {
	value	interface{}
	show	bool  // 控制是否显示变量
}

type VarMemManager struct {
	mem		map[string] memNode
}

func CreateMemManager() VarMemManager {
	return VarMemManager{
		mem: make(map[string]memNode),
	}
}

func (self *VarMemManager) Get(key string) Token {
	v, ok := self.mem[key]
	if ok {
		return v.value.(Token)
	} else {
		println("自动定义变量" + key)
		self.SetValue(key, FromFloat64(0))
		return self.mem[key].value.(Token)
	}
}

func (self *VarMemManager) GetValue(key string) (Token, bool) {
	v, ok := self.mem[key]
	if ok {
		return v.value.(Token), true
	} else {
		return SpcToken(), false
	}
}

func (self *VarMemManager) GetPtr(key string) (Token, bool) {
	_, ok := self.GetValue(key)
	return Token{
		TypeClass: TYPE_PTR,
		Value:     VarPtr{
			locate:  self,
			memType: Var_Mem,
			name:    key,
		},
	}, ok
}

func (self *VarMemManager)MustGetPtr(key string) Token {
	return Token{
		TypeClass: TYPE_PTR,
		Value:     VarPtr{
			locate:  self,
			memType: Var_Mem,
			name:    key,
		},
	}
}

func (self *VarMemManager) SetValue(key string, value Token) {
	self.mem[key] = memNode{value:value, show:true}
}

func (self *VarMemManager) SetValueShow(key string, ifShow bool) {
	if _, ok := self.mem[key]; ok {
		tmp := self.mem[key]
		tmp.show = ifShow
		self.mem[key] = tmp
	} else {
		panic(key + "不存在，不能设置显示")
	}
}

func (self *VarMemManager) NewValue(key string, value Token, isShow bool) bool {
	if _, ok := self.mem[key]; ok {
		return false
	} else {
		self.mem[key] = memNode{value:value, show:isShow}
		return true
	}
}

func (self *VarMemManager) GetMemList() (result []string) {
	for k, v := range self.mem{
		if v.show {
			result = append(result, k + ": " + v.value.(Token).ValueStr())
		}
	}
	return result
}


type FunMemManager struct {
	mem		map[string] memNode
}

func CreateFunMemManager() FunMemManager {
	return FunMemManager{
		mem: make(map[string]memNode),
	}
}

func (self *FunMemManager) Get(key string) func(v Token) Token {
	v, ok := self.mem[key]
	if ok {
		return v.value.(func(v Token) Token)
	} else {
		panic("读取变量" + key +"不存在")
	}
}

func (self *FunMemManager) GetValue(key string) (func(v Token) Token, bool) {
	v, ok := self.mem[key]
	if ok {
		return v.value.(func(v Token) Token), true
	} else {
		return nil, false
	}
}

func (self *FunMemManager) SetValue(key string, value func(v Token) Token) {
	self.mem[key] = memNode{value:value, show:true}
}

func (self *FunMemManager) SetValueShow(key string, ifShow bool) {
	if _, ok := self.mem[key]; ok {
		tmp := self.mem[key]
		tmp.show = ifShow
		self.mem[key] = tmp
	} else {
		panic(key + "不存在，不能设置显示")
	}
}

func (self *FunMemManager) NewValue(key string, value func(v Token) Token, ifShow bool) bool {
	if _, ok := self.mem[key]; ok {
		return false
	} else {
		self.mem[key] = memNode{value:value, show:ifShow}
		return true
	}
}

func (self *FunMemManager) GetMemList() (result []string) {
	for k, v := range self.mem{
		if v.show {
			result = append(result, k)
		}
	}
	return result
}


type RawFunMemManager struct {
	mem		map[string] memNode
}

func CreateRawFunMemManager() RawFunMemManager {
	return RawFunMemManager{
		mem: make(map[string]memNode),
	}
}

func (self *RawFunMemManager) Get(key string) func(ip *Interpreter, v []Expr) Token {
	v, ok := self.mem[key]
	if ok {
		return v.value.(func(ip *Interpreter, v []Expr) Token)
	} else {
		panic("读取变量" + key +"不存在")
	}
}

func (self *RawFunMemManager) GetValue(key string) (func(ip *Interpreter, v []Expr) Token, bool) {
	v, ok := self.mem[key]
	if ok {
		return v.value.(func(ip *Interpreter, v []Expr) Token), true
	} else {
		return nil, false
	}
}

func (self *RawFunMemManager) SetValue(key string, value func(ip *Interpreter, v []Expr) Token) {
	self.mem[key] = memNode{value:value, show:true}
}

func (self *RawFunMemManager) SetValueShow(key string, ifShow bool) {
	if _, ok := self.mem[key]; ok {
		tmp := self.mem[key]
		tmp.show = ifShow
		self.mem[key] = tmp
	} else {
		panic(key + "不存在，不能设置显示")
	}
}

func (self *RawFunMemManager) NewValue(key string, value func(ip *Interpreter, v []Expr) Token, ifShow bool) bool {
	if _, ok := self.mem[key]; ok {
		return false
	} else {
		self.mem[key] = memNode{value:value, show:ifShow}
		return true
	}
}

func (self *RawFunMemManager) GetMemList() (result []string) {
	for k, v := range self.mem{
		if v.show {
			result = append(result, k)
		}
	}
	return result
}


type VarLocate uint

const (
	Var_Mem	VarLocate = 1
)

type VarPtr struct {
	locate	interface{}
	memType	VarLocate
	name	string
}

func SetPtrValue(ptr Token, value Token) {
	if ptr.TypeClass != TYPE_PTR {
		panic("传入参数不是变量指针类型")
	}
	p := ptr.Value.(VarPtr)
	switch p.memType {
	case Var_Mem:
		p.locate.(*VarMemManager).SetValue(p.name, value)
	default:
		panic("无法识别的内存位置")
	}
}

func GetPtrValue(ptr Token) Token {
	if ptr.TypeClass != TYPE_PTR {
		panic("传入参数不是变量指针类型")
	}
	p := ptr.Value.(VarPtr)
	switch p.memType {
	case Var_Mem:
		return p.locate.(*VarMemManager).Get(p.name)
	default:
		panic("无法识别的内存位置")
	}
}

func MustGetPtrValue(ptr Token) Token {
	if ptr.TypeClass != TYPE_PTR {
		return ptr
	}
	p := ptr.Value.(VarPtr)
	switch p.memType {
	case Var_Mem:
		return p.locate.(*VarMemManager).Get(p.name)
	default:
		panic("无法识别的内存位置")
	}
}